package tech.edwardvan.springsecuritydemo.security.config;

import org.springframework.context.ApplicationContext;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import tech.edwardvan.springsecuritydemo.security.filter.JwtAuthenticationProcessingFilter;
import tech.edwardvan.springsecuritydemo.security.filter.JwtTokenAuthenticationFilter;
import tech.edwardvan.springsecuritydemo.security.handler.JwtAuthenticationFailureHandler;
import tech.edwardvan.springsecuritydemo.security.handler.JwtAuthenticationSuccessHandler;
import tech.edwardvan.springsecuritydemo.security.util.JwtTokenUtil;

/**
 * 自定义Jwt配置类
 *
 * @author EdwardVan
 */
public class JwtConfigurer<H extends HttpSecurityBuilder<H>> extends AbstractHttpConfigurer<JwtConfigurer<H>, H> {

    private JwtAuthenticationProcessingFilter authFilter;

    private JwtTokenAuthenticationFilter tokenFilter;

    private AuthenticationSuccessHandler successHandler;

    private AuthenticationFailureHandler failureHandler;

    @Override
    public void init(H http) {
        //获取jwt工具
        JwtTokenUtil jwtTokenUtil = http.getSharedObject(ApplicationContext.class).getBean(JwtTokenUtil.class);
        //初始化Jwt认证过滤器
        this.authFilter = new JwtAuthenticationProcessingFilter();
        //初始化Token校验过滤器
        this.tokenFilter = new JwtTokenAuthenticationFilter(jwtTokenUtil);
        //初始化jwt认证成功处理器
        this.successHandler = new JwtAuthenticationSuccessHandler(jwtTokenUtil);
        //初始化jwt认证失败处理器
        this.failureHandler = new JwtAuthenticationFailureHandler();
    }

    @Override
    public void configure(H http) {
        this.authFilter.setAuthenticationManager(http.getSharedObject(AuthenticationManager.class));
        this.authFilter.setAuthenticationSuccessHandler(this.successHandler);
        this.authFilter.setAuthenticationFailureHandler(this.failureHandler);
        http.addFilterBefore(this.authFilter, UsernamePasswordAuthenticationFilter.class);
        http.addFilterBefore(this.tokenFilter, UsernamePasswordAuthenticationFilter.class);
    }

}
